package work.month06.day28;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Comparator;

/**
 * @date 2020/06/28
 * @author 王光浩
 * @introduction 将给定目录中的相关文件合并到一个给定的文件中
 */
public class FileCombiner {

	// 比较器，用于保证将文件按照分割的顺序依次进行合并
	private final Comparator<File> comparator;

	private FileCombiner(Comparator<File> comparator) {
		this.comparator = comparator;
	}

	/**
	 * 使用默认的排序方法进行排序
	 * @return FileCombiner 实例
	 */
	public static FileCombiner getInstance() {
		// 按照最后两个下划线之间的数字进行比较
		Comparator<File> comparator = new Comparator<File>() {
			@Override
			public int compare(File o1, File o2) {
				String fileName1 = o1.getName();
				String fileName2 = o2.getName();
				String valueo1 = fileName1.substring(fileName1.lastIndexOf("_", fileName1.lastIndexOf("_") - 1) + 1,
						fileName1.lastIndexOf("_"));
				String valueo2 = fileName2.substring(fileName2.lastIndexOf("_", fileName2.lastIndexOf("_") - 1) + 1,
						fileName2.lastIndexOf("_"));
				return Integer.parseInt(valueo1) - Integer.parseInt(valueo2);
			}

		};
		return new FileCombiner(comparator);
	}

	/**
	 * 传入一个 Comparator 对象，对文件进行排序
	 * @param comparator 比较器
	 * @return FileCombiner 实例
	 */
	public static FileCombiner getInstance(Comparator<File> comparator) {
		return new FileCombiner(comparator);
	}

	/**
	 * 将 path 中的文件排序之后，依次写入到 dest 文件中
	 * @param path 需要合并的目录
	 * @param dest 存放合并后内容的文件
	 */
	public void combine(File path, File dest) {
		// 对参数进行检测
		if (path == null || !path.exists() || !path.isDirectory())
			throw new IllegalArgumentException("需要合并的目录不正确");
		if (dest == null || !dest.exists() || !dest.isFile())
			throw new IllegalArgumentException("合并之后的大文件的存储的文件不正确");

		// 定义相关参数
		InputStream in = null;
		OutputStream out = null;
		byte[] buffer = null;

		// 合并文件
		try {
			// 1、获取 path 下的所有文件，然后对文件进行排序
			out = new FileOutputStream(dest);
			File[] listFiles = path.listFiles();
			Arrays.sort(listFiles, this.comparator);
			
			// 2、将 path 下的文件依次写入到 dest 文件中
			for (File f : listFiles) {
				buffer = new byte[(int) f.length()];
				try {
					in = new FileInputStream(f);
					in.read(buffer);
				} catch (IOException e) {
					System.out.println("读入数据出现问题");
				} finally {
					if (in != null)
						try {
							in.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
				}
				out.write(buffer);
			}
		} catch (IOException e) {
			System.out.println("写入数据出现问题");
		} finally {
			// 3、资源的释放
			try {
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
